package tv.accedo.achi.dao;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Component;

import tv.accedo.achi.model.Achi;
import tv.accedo.achi.model.Camp;


/**
 * A dao class with campaign model database operations.
 * @author Bo Liang
 *
 */
@Component
public class CampDao {
	
	private SessionFactory sessionFactory; //injection
	private Camp camp; //injection
	
	/**
	 * Get available campaign object.
	 * <p>only the campaign's end date is greater than current system date,
	 * this campaign are able to add to the campaign list and return.
	 * @return List with campaign object
	 */
	public List<Camp> getAvailableCamps() {
		List<Camp> campList = new ArrayList<Camp>(); 
		Session session = null; 
		try {
//			session = SessionFactoryUtil.getSessionFactory().openSession(); 
			session = sessionFactory.openSession();
			Query query = session.createQuery("from Camp camp where camp.camp_end >= ?")
						.setParameter(0, new Date()); 
			campList = query.list();  
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
//			SessionFactoryUtil.closeSession(session);
			session.close();
		}
		return campList; 
	}
	
	/**
	 * Get user's all unlocked campaigns id by using user id.
	 * @param user_id	user id
	 * @return 			List with campaign id
	 */
	public Map<Integer, String> getUnlockedCampsIdByUserId(int user_id) {
		List<Integer> unlockedCampIdList = new ArrayList<Integer>();
		List<Integer> campIdList = new ArrayList<Integer>();
		Map<Integer, String> returnMap = new HashMap<Integer, String>();
		int camp_id; 
		Session session = null; 
		try {
//			session = SessionFactoryUtil.getSessionFactory().openSession(); 
			session = sessionFactory.openSession();
			Query query = session.createSQLQuery("select camp_id from t_user_camp where user_id = ? and unlock_flag = 2")
					.setParameter(0, user_id); 
			unlockedCampIdList = query.list();  
			query = session.createSQLQuery("select camp_id from t_user_camp where user_id = ?")
					.setParameter(0, user_id); 
			campIdList = query.list(); 
			
			for (Iterator<Integer> iter = campIdList.iterator(); iter.hasNext(); ) {
				camp_id = iter.next(); 
				if (unlockedCampIdList.contains(camp_id)) {
					returnMap.put(camp_id, "finished");
				} else {
					returnMap.put(camp_id, "playing");
				}
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
//			SessionFactoryUtil.closeSession(session);
			session.close();
		}
		
		return returnMap; 
	}
	
	/**
	 * Get all achievements which refer to the specific campaign.
	 * @param camp_sn	campaign serial number
	 * @return			Set with achievement object
	 */
	public Set<Achi> getAchisByCampsn(String camp_sn) {
		Set<Achi> achiSet = new HashSet<Achi>(); 
		Session session = null; 
		try {
//			session = SessionFactoryUtil.getSessionFactory().openSession(); 
			session = sessionFactory.openSession();
			Query query = session.createQuery("from Camp camp where camp.camp_sn = ?")
					.setParameter(0, camp_sn); 
			camp = (Camp)query.uniqueResult(); 
			achiSet = camp.getAchis(); 
		
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
//			SessionFactoryUtil.closeSession(session);
			session.close();
		}
		return achiSet; 
	}
	
	/**
	 * Get all campaign id which has the specific achievement by using achievement id.
	 * @param achi_id	achievement id
	 * @return			List with campaign id
	 */
	public List<Integer> getCampsIdByAchiId(int achi_id) {
		List<Integer> campIdList = new ArrayList<Integer>();
		Session session = null;
		try {
//			session = SessionFactoryUtil.getSessionFactory().openSession(); 
			session = sessionFactory.openSession();
			Query query = session.createSQLQuery("select camp_id from t_camp_achi where achi_id = ?")
					.setParameter(0, achi_id); 
			campIdList = query.list(); 
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
//			SessionFactoryUtil.closeSession(session);
			session.close();
		}
		return campIdList; 
	}

	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	@Resource
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	public Camp getCamp() {
		return camp;
	}

	@Resource
	public void setCamp(Camp camp) {
		this.camp = camp;
	}
	

}
